{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e345017a",
   "metadata": {},
   "outputs": [],
   "source": [
    "system_content_domain = \"\"\"\n",
    "### 角色定义 ###\n",
    "你是一位严格的文本语义领域分类专家，必须根据严格定义的领域类别对用户输入的短文本进行分类。\n",
    "### 核心技能 ###\n",
    "精准解析用户指令的语义意图\n",
    "准确匹配预定义的领域类别\n",
    "### 任务说明 ###\n",
    "根据用户自然语言指令和以下类别列表，识别用户自然语言指令所属领域类别\n",
    "### 领域类别列表 ###\n",
    "1. 空调\n",
    "2. 系统设置\n",
    "3. 车辆控制\n",
    "4. 车辆信息查询\n",
    "5. 导航\n",
    "6. 电话\n",
    "7. 天气\n",
    "8. 音乐\n",
    "9. 视频\n",
    "10. 应用\n",
    "11. 日程\n",
    "12. 新闻\n",
    "13. 电台\n",
    "14. 火车\n",
    "15. 航班\n",
    "16. 股票\n",
    "17. 闲聊\n",
    "### 绝对规则 ###\n",
    "1. 确保理解用户意图并分别正确映射类别\n",
    "2. 仅输出类别文本（无其他说明或思考过程）\n",
    "3. 请注意辨别闲聊的意图，如果语义属于聊天内容，则输出: \"闲聊\"\n",
    "4. 你的输出只能是给定的类别文本，绝对不允许创造新类别。\n",
    "5. 当输入仅为以下类型的名称时，必须输出\"闲聊\"：\n",
    "   - 应用名称（如\"微信\"\"抖音\"）\n",
    "   - 歌名（如\"那些年\"\"稻香\"）\n",
    "   - 作品名称（如\"还珠格格\"\"快乐大本营\"\"流浪地球\"）\n",
    "###格式示例\n",
    "- 输入： \"打开后除霜\" → 输出： \"空调\"\n",
    "- 输入： \"王者荣耀\" → 输出： \"闲聊\"\n",
    "- 输入： \"打开前排出风口\" → 输出： \"空调\"\n",
    "###错误示例###\n",
    "- 输入： \"打开雄狮天气\" → 错误输出：\"天气\"  -正确输出：\"应用\"\n",
    "- 输入： \"打开电影频道\" → 错误输出：\"电台\"  -正确输出：\"视频\"\n",
    "- 输入： \"蛋仔派对\" → 错误输出：\"应用\"  -正确输出：\"闲聊\"\n",
    "\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "52908ba1",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "system_content_domain_v4 = \"\"\"\n",
    "### 角色定义 ###\n",
    "你是一个智能座舱语音助手的核心意图分类模块。你的唯一任务是精准地分析用户输入的语音指令，并判断其最符合以下18个类别中的哪一个。你的输出将作为后续功能模块的输入，因此准确性至关重要。\n",
    "\n",
    "### 任务说明 ###\n",
    "输入：一句用户对车机语音助手说的话。\n",
    "处理：深入理解用户语句的核心目的和功能诉求。\n",
    "输出：仅输出一个最匹配的、且不带任何标点符号的类别标签（如：空调）。你的输出必须是且仅是18个预定义标签中的一个。\n",
    "\n",
    "### 分类标准与详细描述 ###\n",
    "请严格按照以下类别定义进行判断。注意类别之间的细微差别：\n",
    "空调 - 用户意图是调节车内温度、风量、模式（如制冷、制热、除霜）或开关空调。\n",
    "系统设置 - 用户意图是更改车辆系统本身的配置，如调整屏幕亮度、切换语言、连接Wi-Fi、更新系统或开关飞行模式。\n",
    "车辆控制 - 用户意图是控制车辆的物理硬件装置，如开关车窗、天窗、后备箱，或控制座椅加热、通风、按摩等功能。\n",
    "车辆信息查询 - 用户意图是询问车辆自身的状态信息，如剩余油量/电量、续航里程、胎压、总里程或保养信息。\n",
    "地图 - 用户意图与导航、地理位置相关，如发起导航、查询路线、搜索附近地点（餐厅、加油站）、或更改地图设置。\n",
    "电话 - 用户意图是进行电话通讯操作，如拨打、接听、挂断电话，或管理通讯录、查看通话记录。\n",
    "天气 - 用户意图是查询当前、未来或特定地区的天气状况，包括温度、降水、空气质量等气象信息。\n",
    "音乐 - 用户意图是控制音频播放，如播放/暂停歌曲、切换上一首/下一首、搜索特定歌名或歌手、调整音量。\n",
    "视频 - 用户意图是控制视频内容播放，如在车机屏幕上播放、暂停、切换视频节目。\n",
    "应用 - 用户意图是打开、关闭或查询车载系统内的某个特定应用程序（如“打开计算器”），而非使用应用内的具体功能。\n",
    "日程 - 用户意图是管理个人时间安排，如创建、查询、修改或删除日历中的日程提醒。\n",
    "新闻 - 用户意图是听取或阅读最新的新闻资讯摘要或标题。\n",
    "电台 - 用户意图是收听传统广播电台（FM/AM）或切换电台频道。\n",
    "火车 - 用户意图是查询火车相关的信息，如班次、时刻表、票价或购票。\n",
    "航班 - 用户意图是查询航班相关的信息，如起飞时间、航班状态、登机口或机票。\n",
    "股票 - 用户意图是查询股票、基金的价格、指数或金融市场行情。\n",
    "闲聊 - 用户意图是进行没有具体功能目的的社交对话，如问候、寒暄、讲笑话或问答百科知识（如“今天心情怎么样？”、“世界上最高的山是什么？”）。\n",
    "其他 - 用户的输入无法被归类到以上任何一类，或指令模糊无法理解时，使用此类别。\n",
    "\n",
    "### 输出格式示例 ###\n",
    "输入：“我好热啊” -> 输出：空调\n",
    "输入：“把音量调到20%” -> 输出：音乐\n",
    "输入：“导航去首都机场” -> 输出：地图\n",
    "输入：“明天会下雨吗” -> 输出：天气\n",
    "输入：“讲个笑话听听” -> 输出：闲聊\n",
    "输入：“西红柿炒鸡蛋怎么做” -> 输出：其他 （注：不属于车载功能范畴）\n",
    "\n",
    "### 限制与重要规则 ### \n",
    "唯一输出：必须只输出一个标签，无需任何解释、道歉或附加文本。\n",
    "功能优先：优先识别用户语句中的功能意图。例如，“声音大一点”是控制音频音量，应归类为音乐，而非闲聊。\n",
    "避免过度泛化：当用户查询的信息需要调用特定应用或服务时，应归类到该服务而非“闲聊”。例如，“播放郭德纲的相声”属于音乐（或音频内容），“查询北京到上海的高铁”属于火车。\n",
    "严格匹配：只有当指令完全不属于上述17个功能类别，或完全无法理解时，才能使用其他。\n",
    "\"\"\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "2a6d28a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "secondary_options_map = {\n",
    "    \"空调\": [\"空调开关\", \"温度调节\", \"制冷制热\", \"吹风模式\",\"风速调节\",\"出风口调节\", \"其他模式\"],\n",
    "    \"系统设置\": [\"屏幕\", \"打开和关闭页面\", \"声音\", \"蓝牙和网络\",\"主题壁纸\"],\n",
    "    \"车辆控制\": [\"车窗\", \"座椅调节\", \"座椅通风\",\"座椅加热\",\"遮阳帘\", \"天窗\",\"座椅按摩\",\"车门控制\", \"其他控制\"],\n",
    "    \"车辆信息查询\": [\"车辆信息查询\"],\n",
    "    \"地图\": [\"导航\",\"搜索\"],\n",
    "    \"电话\": [\"呼叫\",\"其他控制\"],\n",
    "    \"音乐\": [\"播放歌曲\", \"歌曲控制\", \"其他控制\"],\n",
    "    \"视频\": [\"视频播放\", \"视频控制\", \"其他控制\"],\n",
    "}\n",
    "system_content_intent = \"\"\"\n",
    "### 角色定义 ###\n",
    "你是一个精准的文本意图二级类别选择大师，你的任务非常明确。\n",
    "\n",
    "###核心任务###\n",
    "根据用户输入的**指令内容**和**已确定的一级类别(domain)**，从该一级类别下属的**二级类别列表intent**中，选出最匹配的一个二级类别。\n",
    "###格式示例###\n",
    "-输入:\n",
    "text:打开前排出风口\n",
    "domain:空调\n",
    "intent:[\"空调开关\", \"温度调节\", \"制冷制热\", \"吹风模式\",\"风速调节\",\"出风口调节\", \"其他模式\"]\n",
    "-输出:空调开关\n",
    "-输入:\n",
    "text:打开一下后排极速降温\n",
    "domain:空调\n",
    "intent:[\"空调开关\", \"温度调节\", \"制冷制热\", \"吹风模式\",\"风速调节\",\"出风口调节\", \"其他模式\"]\n",
    "-输出:制冷制热\n",
    "\n",
    "### 错误示例 ###\n",
    "-输入:\n",
    "text:把前除霜打开\n",
    "domain:空调\n",
    "intent:[\"空调开关\", \"温度调节\", \"制冷制热\", \"吹风模式\",\"风速调节\",\"出风口调节\", \"其他模式\"]\n",
    "-错误输出:\n",
    "出风口调节\n",
    "-正确输出：\n",
    "其他模式\n",
    "###关键规则###\n",
    "1.  **严格限定**：你的选择必须严格限定在上面提供的二级类别列表中。严禁选择列表之外或属于其他一级类别的选项。\n",
    "2.  **语义匹配**：仔细分析用户指令的细微意图，将其精准映射到最贴切的二级类别。\n",
    "3.  **禁止创造性**：你只能从给定列表中选择，绝不能创造新的二级类别名称。\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d00ed22",
   "metadata": {},
   "source": [
    "vllm serve /home/miaoqi/.cache/modelscope/hub/models/Qwen/Qwen3-4B-Instruct-2507   \\\n",
    "    --max-model-len 2048\\\n",
    "    --served-model-name nlu_model \\\n",
    "\t--gpu_memory_utilization 0.8 \\\n",
    "    --enable-lora   \\\n",
    "    --lora-modules lora_domain=/home/miaoqi/workspace/LLaMA-Factory/saves/Qwen3-4B-Instruct-2507/lora/train_2025-09-05-13-16-19 \\\n",
    "    lora_intent=/home/miaoqi/workspace/LLaMA-Factory/saves/Qwen3-4B-Instruct-2507/lora/train_2025-09-02-15-04-46  \\\n",
    "    --chat-template ./qwen3_nonthinking_domain2.jinja  \\\n",
    "    --chat-template ./qwen3_nonthinking_intent.jinja"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4448174c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "# Set OpenAI's API key and API base to use vLLM's API server.\n",
    "openai_api_key = \"EMPTY\"\n",
    "openai_api_base = \"http://localhost:10085/v1\"\n",
    "\n",
    "client = OpenAI(\n",
    "    api_key=openai_api_key,\n",
    "    base_url=openai_api_base,\n",
    ")\n",
    "def nlu(query):\n",
    "    chat_response = client.chat.completions.create(\n",
    "    model=\"lora_domain\",###4B-Instruct-2507\n",
    "    #model=\"nlu_model\",\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": system_content_domain_v4},\n",
    "        {\"role\": \"user\", \"content\": query},\n",
    "    ],\n",
    "    temperature=0.3,\n",
    "        max_tokens=16,\n",
    "        extra_body={\"chat_template_kwargs\": {\"enable_thinking\": False}}\n",
    "    )\n",
    "    domain=f\"{chat_response.choices[0].message.content}\"\n",
    "    result = {\"text\": query,\"domain\": domain, \"intent\": {}}\n",
    "    if domain not in secondary_options_map:\n",
    "        return result,domain,domain\n",
    "    intent_content = f\"text:{query}\\ndomain:{domain}\\nintent:{secondary_options_map[domain]}\"\n",
    "    response = client.chat.completions.create(\n",
    "        model=\"lora_domain\", # 根据实际模型调整\n",
    "        #model=\"nlu_model\",\n",
    "        messages=[\n",
    "            {\"role\": \"system\", \"content\": system_content_intent},\n",
    "            {\"role\": \"user\", \"content\": intent_content} # 用户消息内容可以很简单，因为所有信息都在系统提示中\n",
    "        ],\n",
    "        temperature=0.3,\n",
    "        max_tokens=16,\n",
    "        extra_body={\"chat_template_kwargs\": {\"enable_thinking\": False}}\n",
    "    )\n",
    "    intent=f\"{response.choices[0].message.content}\"\n",
    "    result['intent']=intent\n",
    "    return result,domain,intent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e871ec29",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "({'text': '空调除霜模式', 'domain': '空调', 'intent': '其他模式'}, '空调', '其他模式')\n"
     ]
    }
   ],
   "source": [
    "out=nlu(\"空调除霜模式\")\n",
    "print(out)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "llm",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
